﻿using ProjectCommonLibs.utils;
using SocketServer.constVars;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SocketServer
{
    class Program
    {
        //private static readonly string connectString = "server=127.0.0.1;user id=root;password=hua991b8;database=dongtai;Charset=utf8mb4";

        static void Main(string[] args)
        {
            var timeMillis = GetJavaTimeInMillis(DateTime.UtcNow);
            Console.WriteLine(timeMillis);
            int port = 8080;
            if (args.Length > 0)
            {
                port = Convert.ToInt32(args[0]);
            }
            var random = new Random();
            bool listening = true;
            var listener = new TcpListener(IPAddress.Any, port);
            listener.Start();
            //var v6Listener = new TcpListener(IPAddress.IPv6Any, port);
            //v6Listener.Start();
            Console.WriteLine($"正在监听{port}端口\r\n");
            while (listening)
            {
                var socket = listener.AcceptSocket();
                Task.Run(() =>
                {
                    try
                    {
                        string remoteSocket = socket.RemoteEndPoint.ToString();
                        byte[] buffer = Enumerable.Repeat((byte)0x20, 1024).ToArray();

                        


                        //Console.WriteLine($"{remoteSocket}连接本机");
                        //int i = socket.Receive(buffer);//接受连接请求的字节流
                        //var registerCommand = Encoding.UTF8.GetString(buffer).Trim();
                        //string msg = "<" + remoteSocket + ">" + registerCommand;
                        //Console.WriteLine(DateTime.Now);
                        //Console.WriteLine(msg);//在控制台显示字符串
                        while (socket.Connected)
                        {
                            var i = socket.Receive(buffer);
                            int index = 0;
                            while (index < i)
                            {
                                var channel = BitConverter.ToInt32(buffer, index);
                                index += 4;
                                var canID = BitConverter.ToInt32(buffer, index);
                                index += 4;
                                var frameType = BitConverter.ToInt32(buffer, index); index += 4;
                                var length = BitConverter.ToInt32(buffer, index); index += 4;
                                var timeInMillis = BitConverter.ToInt64(buffer, index); index += 8;
                                var time = ToCSharpTime(timeInMillis).ToShortTimeString();
                                var data = buffer.Skip(index).Take(length);
                                var dataString = string.Join(" ", data.Select(x => $"{x:X2}"));
                                index += length;
                                Console.WriteLine($"channel：{channel:X},canID：{canID:X},frameType：{frameType:X},time：{time},data：{dataString}");
                            }
                            var packet = new List<byte>();
                            var frameCount = random.Next(4, 9);
                            
                            for (int j = 0; j < frameCount; j++)
                            {
                                var canID = random.Next();
                                var channel = random.Next(0x03);
                                var frameType = random.Next(3);
                                var length = random.Next(0x40);
                                packet.AddRange(BitConverter.GetBytes(channel));
                                packet.AddRange(BitConverter.GetBytes(canID));
                                packet.AddRange(BitConverter.GetBytes(frameType));
                                packet.AddRange(BitConverter.GetBytes(length));
                                packet.AddRange(BitConverter.GetBytes(GetJavaTimeInMillis(DateTime.UtcNow)));
                                for (int k = 0; k < length; k++)
                                {
                                    packet.Add((byte)random.Next());
                                }
                            }
                            packet.Add(0x0d);
                            packet.Add(0x0a);
                            var sendMessage = String.Join(" ",packet.Select(b => $"{b:X2}"));
                            Console.WriteLine(sendMessage);
                            socket.Send(packet.ToArray());
                        }
                        socket.Shutdown(SocketShutdown.Both);
                        socket.Close();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(ex.StackTrace);
                        if (socket.Connected)
                        {
                            socket.Shutdown(SocketShutdown.Both);
                            socket.Close();
                        }
                    }
                });

            }
            //dataBase.closeConnection();
        }

        private static long GetJavaTimeInMillis(DateTime time) => (time.Ticks - new DateTime(1970, 1, 1).Ticks) / TimeSpan.TicksPerMillisecond;
        private static DateTime ToCSharpTime(long time) => new DateTime(1970, 1, 1).AddMilliseconds(time) + TimeSpan.FromHours(8);
    }
}
